package com.base.lock.aop;


import com.base.lock.LockKeyBuilder;
import com.base.lock.LockInfo;
import com.base.lock.LockTemplate;
import com.base.lock.annotation.Lock;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;


/**
 * 分布式锁aop处理器
 *
 * @author carl
 */
@Slf4j
@RequiredArgsConstructor
public class LockInterceptor implements MethodInterceptor {

    private final LockTemplate lockTemplate;

    private final LockKeyBuilder lockKeyBuilder;

    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        LockInfo lockInfo = null;
        try {
            Lock lock = invocation.getMethod().getAnnotation(Lock.class);
            String key = lockKeyBuilder.buildKey(invocation, lock);
            lockInfo = lockTemplate.lock(key, lock.expire(), lock.acquireTimeout(), lock.executor());
            if (null != lockInfo) {
                return invocation.proceed();
            }
            return null;
        } finally {
            if (null != lockInfo) {
                final boolean releaseLock = lockTemplate.releaseLock(lockInfo);
                if (!releaseLock) {
                    log.error("releaseLock fail,lockKey={},lockValue={}", lockInfo.getLockKey(),
                            lockInfo.getLockValue());
                }
            }
        }
    }

}
